package com.aabte.nettyleran.netty.privateprotocolstack;

import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;

import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author Daniel
 * @version 1.0
 * @date 2020/3/15
 */
public class LoginAuthRespHandler extends ChannelHandlerAdapter {

    /**
     * remoteAddress  ->   true | false
     */
    private Map<String, Boolean> nodeCheck = new ConcurrentHashMap<>();

    private String[] whiteList = {
            "127.0.0.1",
            "192.168.1.104"
    };

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        NettyMessage message = (NettyMessage) msg;
        System.out.println("message = " + message);

        if (message.getHeader() != null && message.getHeader().getType() == MessageType.LOGIN_REQ.getValue()) {
            // 是登陆请求消息
            String remoteAddress = ctx.channel().remoteAddress().toString();
            NettyMessage loginResp = null;

            if (nodeCheck.containsKey(remoteAddress)) {
                // 重复登录，拒绝
                loginResp = buildResponse((byte) -1);
            } else {
                InetSocketAddress address = (InetSocketAddress) ctx.channel().remoteAddress();
                String ip = address.getAddress().getHostAddress();
                boolean isOk = false;
                for (String wip : whiteList) {
                    if (wip.equalsIgnoreCase(ip)) {
                        isOk = true;
                        break;
                    }
                }
                loginResp = isOk ? buildResponse((byte) 0) : buildResponse((byte) -1);
                if (isOk) {
                    nodeCheck.put(remoteAddress, true);
                }
                System.out.println("The login response is: " + loginResp + " body [" + loginResp.getBody() + "]");
                ctx.writeAndFlush(loginResp);
            }
        } else {
            ctx.fireChannelRead(msg);
        }
    }

    private NettyMessage buildResponse(byte result) {

        Header header = Header.builder()
                .type(MessageType.LOGIN_RESP.value())
                .attachment(new HashMap<>(0))
                .build();

        return NettyMessage.builder()
                .header(header)
                .body(result)
                .build();

    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        nodeCheck.remove(ctx.channel().remoteAddress().toString());
        cause.printStackTrace();
        ctx.close();
        ctx.fireExceptionCaught(cause);
    }
}
